import UI_Inspector from "../../ui/Main/UI_Inspector";
import BaseUIMediator from "../../LTGame/UI/BaseUIMediator";
import { CmpObjTitle } from "./cmp/CmpObjTitle";
import { EventCenter } from "../../LTGame/Event/EventCenter";
import { EventIDs } from "../common/EventIds";
import { BaseViewCmp } from "./cmp/BaseViewCmp";
import { DebuggerManager } from "../debugger/DebuggerManager";
import { TransPack } from "../../server/framework/common/TransPack";
import { EMessageC2C } from "../../common/EMessageC2C";
import { ViewStatus } from "./view/ViewStatus";
import { DetailData } from "../debug_inject/handler/HandleQueryObjDetail";
import { BaseCmpData } from "../debug_inject/common/BaseCmpData";
import { EObjCmpType } from "../debug_inject/common/EObjCmpType";
import ArrayEx from "../../LTGame/Utils/ArrayEx";
import { CmpTransform3D } from "./cmp/CmpTransform3D";
import MonoHelper, { EActionType } from "../../LTGame/Utils/MonoHelper";
import { CmpScene3D } from "./cmp/CmpScene3D";
import { CmpCamera } from "./cmp/CmpCamera";

export default class UI_InspectorMediator extends BaseUIMediator<UI_Inspector> {

    private static _instance: UI_InspectorMediator;
    public static get instance(): UI_InspectorMediator {
        if (this._instance == null) {
            this._instance = new UI_InspectorMediator();
            this._instance._classDefine = UI_Inspector;
        }
        return this._instance;
    }

    private _cacheObjId: number;

    private _cacheCmps: BaseViewCmp[];

    private _viewStatus: ViewStatus;

    private _skipTime: number;

    _OnShow() {
        super._OnShow();
        // your code
        this.ui.setXY(this.ui.parent.width - this.ui.width - 10, 10);
        this.ui.setSize(this.ui.width, this.ui.parent.height - 20);

        this._cacheObjId = null;
        this._skipTime = 1;

        this._viewStatus = new ViewStatus(this.ui.m_view_status);

        this._cacheCmps = [];
        this.ui.m_btn_refresh.onClick(this, this._OnClickRefresh);

        EventCenter.instance.Regist(EventIDs.SelectObj, this, this._OnSelectObj);

        DebuggerManager.instance.RegistClientMsg(EMessageC2C.QueryObjDetail_Back, this, this._OnObjDetailBack);

        MonoHelper.instance.AddAction(EActionType.Update, this, this._LogicUpdate);
    }

    _OnHide() {
        MonoHelper.instance.RemoveAction(EActionType.Update, this, this._LogicUpdate);

        EventCenter.instance.UnRegist(EventIDs.SelectObj, this, this._OnSelectObj);

        DebuggerManager.instance.UnRegistClientMsg(EMessageC2C.QueryObjDetail_Back);
    }

    private _LogicUpdate(dt: number) {
        if (!this._viewStatus.isQuery) {
            this._skipTime -= dt;
            if (this._skipTime < 0) {
                this._QueryObjDetails();
            }
        }
    }

    private _OnObjDetailBack(pack: TransPack) {
        this._viewStatus.isQuery = false;
        this._skipTime = 0.1;
        let data = pack.data as DetailData;
        if (data.code == -1) {
            this.ui.m_view_notice.visible = true;
            this._HideAllCmps();
            EventCenter.instance.Send(EventIDs.RefreshObjList, null);
            return;
        }
        if (data.objId != this._cacheObjId) return;
        for (let i = 0; i < data.cmps.length; ++i) {
            let getCmpData = data.cmps[i];
            let getCacheCmp = this._cacheCmps[i];
            if (getCacheCmp == null) {
                getCacheCmp = this._GenNewCmp(getCmpData);
            } else if (getCacheCmp.type != getCmpData.type) {
                // 从该节点往后,全部清空
                console.log("错位,清空");
                for (let j = i; j < this._cacheCmps.length; ++j) {
                    this._cacheCmps[j].Dispose();
                }
                let newCmpArray: BaseViewCmp[] = [];
                for (let j = 0; j < i; ++j) {
                    newCmpArray.push(this._cacheCmps[j]);
                }
                this._cacheCmps = newCmpArray;

                // 创建新的
                getCacheCmp = this._GenNewCmp(getCmpData);
            }

            getCacheCmp?.Refresh(getCmpData, this._cacheObjId);
        }

        // 清空多余
        let isCleared: boolean = false;
        for (let i = data.cmps.length; i < this._cacheCmps.length; ++i) {
            this._cacheCmps[i].Dispose();
            isCleared = true;
        }
        if (isCleared) {
            let newCmpArray: BaseViewCmp[] = [];
            for (let i = 0; i < data.cmps.length; ++i) {
                newCmpArray.push(this._cacheCmps[i]);
            }
            this._cacheCmps = newCmpArray;
        }
    }

    private _GenNewCmp(getCmpData: BaseCmpData): BaseViewCmp {
        let getCacheCmp = this._CreateCmp(getCmpData);
        if (getCacheCmp == null) {
            return null;
        }
        this.ui.m_list_cmps.addChild(getCacheCmp.ui);
        this._cacheCmps.push(getCacheCmp);
        return getCacheCmp;
    }

    private _CreateCmp(cmpData: BaseCmpData): BaseViewCmp {
        switch (cmpData.type) {
            case EObjCmpType.Base:
                return new CmpObjTitle(this._cacheObjId);
            case EObjCmpType.Transform3D:
                return new CmpTransform3D(this._cacheObjId);
            case EObjCmpType.Scene3D:
                return new CmpScene3D(this._cacheObjId);
            case EObjCmpType.Camera:
                return new CmpCamera(this._cacheObjId);
            default:
                console.error("未处理的cmpType:", cmpData);
                return null;
        }
    }

    private _OnSelectObj(objIds: number[]) {
        if (objIds.length > 1) {
            console.error("暂时不支持多obj选择");
            return;
        }
        this.SelectObj(objIds[0]);
    }

    public SelectObj(objId: number) {
        if (this._cacheObjId == objId) return;
        this._cacheObjId = objId;
        if (this._cacheObjId == null) {
            this._HideAllCmps();
            this.ui.m_view_notice.visible = true;
            return;
        }
        this.ui.m_view_notice.visible = false;
        this._QueryObjDetails();
    }

    private _HideAllCmps() {
        for (let i = 0; i < this._cacheCmps.length; ++i) {
            this._cacheCmps[i].Dispose();
        }
        this._cacheCmps = [];
    }

    private _QueryObjDetails() {
        if (this._cacheObjId == null) return;
        if (this._viewStatus.isQuery) return;
        this._viewStatus.isQuery = true;
        DebuggerManager.instance.QueryObjDetails(this._cacheObjId);
    }

    private _OnClickRefresh() {
        this._QueryObjDetails();
    }

}